package com.yth.utils;


/**
 * 异常类工具类
 * <p>部分功能脱离java原本异常的设计功能，选用时请慎重</p>
 *
 * @author jinlang
 * @version 1.0
 * @date 2019-01-31 20:15
 */
public class ThrowHider {

    /**
     * 受检异常隐藏
     * <p>仍能正常抛出原本的受检异常，但编译器无需在方法上强制制定受检异常</p>
     * <p>由于受检异常信息在方法上不展示，可能造成方法使用不当，请慎用</p>
     *
     * @param function
     * @param <V>
     * @return
     */
    public static <V> V exec(CallThrow<V> function) {
        try {
            return function.call();
        } catch (Throwable e) {
            throw propagate(e);
        }
    }

    /**
     * 受检异常隐藏
     * <p>仍能正常抛出原本的受检异常，但编译器无需在方法上强制制定受检异常</p>
     * <p>由于受检异常信息在方法上不展示，可能造成方法使用不当，请慎用</p>
     *
     * @param function
     * @param <E>
     */
    public static <E extends Throwable> void exec(RunThrow function) {
        try {
            function.run();
        } catch (Throwable e) {
            throw propagate(e);
        }
    }

    /**
     * 受检异常隐藏（慎用）
     *
     * @param throwable
     * @param <E>
     * @return
     * @throws E
     */
    public static <E extends Throwable> RuntimeException propagate(Throwable throwable) throws E {
        //noinspection unchecked
        throw (E) throwable;
    }

    @FunctionalInterface
    public interface CallThrow<T> {

        /**
         * 通用函数方法
         */
        T call() throws Throwable;
    }

    @FunctionalInterface
    public interface RunThrow {

        /**
         * 通用函数方法
         */
        void run() throws Throwable;
    }

    private ThrowHider() {
        throw new UnsupportedOperationException();
    }
}
